#include "starfield.h"
#include "sdl_auxiliary.h"
#include "sdl_screen.h"

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define NR_STARS 1000
#define STAR_VELOCITY 0.01
#define MS_BETWEEN_FRAMES 30


StarField::StarField() throw (sdl::Exception)
: _stars(NR_STARS)
{
	sdl::Screen* s = sdl::Screen::getInstance();
	s->setCaption("Starfield");
	// Seed before randomizing
	srand(time(NULL));
	// Randomize position of the stars
	Star::Iter i = _stars.begin();
	for (; i != _stars.end(); ++i) {
		i->randomizePos();
	}
	// Register callbacks
	s->addListener(this);
	sdl::Event::getInstance()->addListener(this);
	// Update on start
	s->update();
	// Start timer
	start(MS_BETWEEN_FRAMES);
	// Enter main loop
	sdl::Event::getInstance()->wait();
}


StarField::~StarField()
{
	// Wait for timer to stop
	stop();
}


Uint32 StarField::onTimer(Uint32 interval)
{
	// Move all stars
	Star::Iter i = _stars.begin();
	for (; i != _stars.end(); ++i) {
		i->move(STAR_VELOCITY);
	}
	// Draw stars
	sdl::Screen::getInstance()->update();
	return interval;
}


void StarField::on(sdl::SurfaceListener::Update, sdl::Surface* s) throw()
{
	s->fill(NULL, 0);
	Star::Iter i = _stars.begin();
	for (; i != _stars.end(); ++i) {
		i->draw(s);
	}
}


void StarField::on(sdl::EventListener::NewEvent, const SDL_Event* e) throw()
{
	if (e->type == SDL_QUIT ||
		(e->type == SDL_KEYDOWN && e->key.keysym.sym == SDLK_ESCAPE))
	{
		sdl::Event::getInstance()->stopWaiting();
	}
}


int main()
{
	try {
		// Init SDL library
		sdl::initialize();
		// Create window
		sdl::Screen::getInstance()->setVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT);
		StarField();
	}
	catch (std::exception& e) {
		// Get rid off warning (format not a string literal
		// and no format arguments)
		fprintf(stderr, "%s", e.what());
		return 1;
	}
	return 0;
}

